package com.jdwx.opengl.kotlin

import kotlin.random.Random


//反射
class Test23{
    constructor( name:String ){
        this.name = name
    }

    fun print(){
        println( "print" )
    }
    fun print2(){
        println( "print2" )
    }
    var name = "baijinhao"
    var age = 100
}

fun isOdd(x: Int) = x % 2 != 0
fun isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove"

fun <T> fun11( name:T,predicate: (T) -> Boolean) {

    var booleanVal = predicate( name )
    println( booleanVal )

}

data class Person3( val name:String, val age : Int)
val xxxx = 1
var xxxx2 = 1
fun aa(name:Int) = { print("我是") }

fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        print("==")
        return it +100
    }
}

fun main(){


    val numberss = listOf(1, 2, 3)
    println(numberss.filter(::isOdd))

    val numbers = listOf(1, 2, 3)
    println(numbers.filter(::isOdd)) // 引用到 isOdd(x: Int)

    val isEmptyStringList: List<String>.() -> Boolean = List<String>::isEmpty

    fun11( 10, ::isOdd );


                          //::isOdd    //::length  string  返回: int  string boolean
    fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
        return { y -> f(g(y)) }
    }
    fun length(s: String) = s.length

    val oddLength = compose(::isOdd, ::length)
    val strings = listOf("a", "ab", "abc")

    println(strings.filter(oddLength))

    var xx  = {x : Int, y : Int -> x + y}

    var xxx  = { x:String -> x.length }

    xxx("xiaobai")

    run{ println( "class H6" ) }


    val person3 = listOf<Person3>(Person3("article",26),
            Person3("book",329),
            Person3("book2",109))

    println( person3.maxBy { it.age })
    //println( person3.maxBy { Person3::age })

    var maxBy = person3.minBy { it.age }
    //1
    maxBy = person3.minBy ( { p:Person3->p.age } )
    //2
    maxBy = person3.minBy (){
        p:Person3->p.age
    }
    //3
    maxBy = person3.minBy{
        p:Person3->p.age
    }
    //4
    maxBy = person3.minBy{
        p->p.age
    }
    //5
    maxBy = person3.minBy{
        it.age
    }

    println( maxBy?.name )

    var aaa = ::aa
    run( aaa(10) )

    println(::xxxx.get())
    println(::xxxx.name)
    println( ::xxxx2.set(10) )
    println( ::xxxx2.get() )

    class A(val p: Int)
    val prop = A::p
    println(prop.get(A(20)))

    Test23(name="xiaobai").let {
        println(it)
        it.print()
        it.print2()
        println(it)
    }

    val str = "Hello"
    // this
    str.run {
        this.length
        println("The receiver string length: $length")
        //println("The receiver string length: ${this.length}") // 和上句效果相同
    }

    // it
    str.let {
        println("The receiver string's length is ${it.length}")
    }

    val adam = Test23("Adam").apply {
        age = 20                       // 和 this.age = 20 或者 adam.age = 20 一样
        name = "London"
    }

    println( "adam.age ==="+ adam.name )



    val i = getRandomInt()

    print( "i="+i )

    val numbers2 = mutableListOf("one", "two", "threed")
    val countEndsWithE = numbers2.run {
        add("four")
        add("five")
        count { it.endsWith("e") }
    }
    println("There are $countEndsWithE elements that end with e.")

    val aaaa = numbers2?.run{
        print("我运行了")
        this.add("10")
        print(this[2])
        this.size
    }

    println(  "aaaa=="+aaaa )


    with(numbers2) {
        val firstItem = first()
        val lastItem = last()
        println("First item: $firstItem, last item: $lastItem")
    }


    val numbers6 = mutableListOf("one", "two", "three", "four", "five")
    var resultList = numbers6.map { it.length }.filter { it > 3 }
    println(resultList)

    //let返回lamda 表达式1
    resultList = numbers6.map { it.length }.filter { it>3 }.let {
        println( "我是结果" )
        println( it )
        it
    }
    println(resultList)
    //let返回lamda 表达式2
    numbers6.map { it.length }.filter { it>3 }.let(::println)

    val str2: String? = "Hello"
    //processNonNullString(str)       // 编译错误：str 可能为空
    val length = str2?.let {
        println("let() called on $it")
        it.length
    }

    val numbers7 = listOf("one", "two", "three", "four")
    var modifiedFirstItem = numbers7.first().let { firstItems ->
        println("The first item of the list is '$firstItems'")
        if (firstItems.length >= 5) firstItems else "!" + firstItems + "!"
    }.toUpperCase()
    println("First item after modifications: '$modifiedFirstItem'")

    modifiedFirstItem = numbers7.first().let {
        println("The first item of the list is '$it'")
        if (it.length >= 5) it else "!" + it + "!"
    }.toUpperCase()
    println("First item after modifications: '$modifiedFirstItem'")


    val numbers8 = mutableListOf("one", "two", "three")
    with(numbers8) {
        println("'with' is called with argument $this")
        println("It contains $size elements")
    }

     class Service{
        var port:Int? = null
        fun query( value:String ){
            print( value )
        }
    }
    var service = Service() //MultiportService("https://example.kotlinlang.org", 80)

    val result = service?.run {
        port = 8080
        query(" to port $port " )
        this
    }

    // 同样的代码如果用 let() 函数来写:
    val letResult = service?.let {
        it.port = 8080
        it.query(" to port ${it.port}")
    }
    service = Service().apply {
        port = 10000
        query( "我的端口是：$port" )
    }

    println( service.port )

    service.let {
        println( it.port )
    }




}

